package com.rd.config.security;

import cn.hutool.jwt.JWT;
import com.rd.common.constant.JwtConstant;
import com.rd.pojo.SysUser;
import com.rd.service.SysUserService;
import com.rd.util.CheckResult;
import com.rd.util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.jar.JarException;

/**
 * 自定义验证请求头中是否包含token值
 * 过滤器  --->拦截器---->控制器
 */
@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Resource
    SysUserService sysUserService;

    @Resource
    MyUserDetailServiceImpl myUserDetailService;

    //过滤器直接放行的路径
    public static final String[] pass = {"/login", "/logout"};

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        //1.获取请求头上的token值
        String token = request.getHeader("token");
        //2.获取请求的uri地址
        String uri = request.getRequestURI();
        log.info("你正在请求{}", uri);
        log.info("请求头中的token值{}", token);
        //3.判断token值是否为null
        if (StringUtil.isNullOrEmpty(token)){
            //4.token为null,则判断是否是放行路径
            boolean flag = Arrays.asList(pass).contains(uri);
            if(flag){
                //放行
                chain.doFilter(request,response);
            }else{
                //没有权限访问
                throw  new JwtException("token值为null，且没有权限不能访问!");
            }
        }else{
            //说明请求头中携带了token值
            CheckResult checkResult = JwtUtil.validateJWT(token);
            if (checkResult.isSuccess()) {
                //验证成功
                //解析token值
                Claims claims = JwtUtil.parseJWT(token);
                String subject = claims.getSubject();
                log.info("解析token值，获取到当前登录的用户名:{}",subject);
                //获取到当前登录用户的详细信息
                SysUser sysUser = sysUserService.getUserByName(subject);
                log.info("当前登录的用户详细信息:{}",sysUser);
                //创建一个用户
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                        =new UsernamePasswordAuthenticationToken(sysUser.getUsername(),null,
                        myUserDetailService.getUserAuthorityList(sysUser.getId()));
                //让上下文填充这个认证
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                //放行
                chain.doFilter(request,response);
            } else {
                //验证失败
                int errCode = checkResult.getErrCode();
                switch (errCode) {
                    case JwtConstant.JWT_ERRCODE_NULL:
                        throw new JwtException("Token值为null");
                    case JwtConstant.JWT_ERRCODE_EXPIRE:
                        throw new JwtException("Token过期");
                    case JwtConstant.JWT_ERRCODE_FAIL:
                        throw new JwtException("Token值验证失败");
                }
            }
        }

    }
}
